package org.jeecg.modules.wms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.oms.entity.ProductSalesOrderDetail;
import org.jeecg.modules.oms.service.IProductSalesOrderDetailService;
import org.jeecg.modules.wms.entity.*;
import org.jeecg.modules.wms.mapper.FinishedGoodsInboundMapper;
import org.jeecg.modules.wms.service.*;
import org.jeecg.modules.wms.vo.FinishedGoodsInboundVO;
import org.jeecg.modules.wms.vo.InboundCreateVO;
import org.jeecg.modules.wms.vo.InboundDetailCreateVO;
import org.jeecg.modules.wms.vo.ProductionTaskVO;
import org.jeecg.modules.wms.vo.BatchInboundExecuteVO;
import org.jeecg.modules.oms.entity.ProductSalesOrder;
import org.jeecg.modules.oms.service.IProductSalesOrderService;
import org.jeecg.modules.mes.entity.MesProductionPlan;
import org.jeecg.modules.mes.entity.MesProductionPlanTask;
import org.jeecg.modules.mes.service.IMesProductionPlanService;
import org.jeecg.modules.mes.service.IMesProductionPlanTaskService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 成品入库Service实现类
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class FinishedGoodsInboundServiceImpl extends ServiceImpl<FinishedGoodsInboundMapper, FinishedGoodsInbound>
        implements IFinishedGoodsInboundService {

    @Autowired
    private FinishedGoodsInboundMapper finishedGoodsInboundMapper;

    @Autowired
    private IFinishedGoodsInboundDetailService inboundDetailService;

    @Autowired
    private IFinishedGoodsInventoryService inventoryService;

    @Autowired
    private IFinishedGoodsInventoryLogService inventoryLogService;

    @Autowired
    private IWmsWarehouseLocationService warehouseLocationService;

    @Autowired
    private IProductSalesOrderService productSalesOrderService;

    @Autowired
    private IProductSalesOrderDetailService productSalesOrderDetailService;

    @Autowired
    private IMesProductionPlanService mesProductionPlanService;

    @Autowired
    private IMesProductionPlanTaskService mesProductionPlanTaskService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createInbound(InboundCreateVO vo) {
        log.info("创建成品入库单，订单号：{}", vo.getOrderNo());

        // 2. 创建入库单主表
        FinishedGoodsInbound inbound = new FinishedGoodsInbound();
        BeanUtils.copyProperties(vo, inbound);
        inbound.setInboundNo(generateInboundNo());
        inbound.setInboundStatus(0); // 待入库
        inbound.setCreateTime(new Date());

        // 计算总数量
        int totalQuantity = vo.getDetailList().stream()
                .mapToInt(InboundDetailCreateVO::getActualQuantity)
                .sum();
        inbound.setTotalQuantity(totalQuantity);

        this.save(inbound);

        // 3. 创建入库明细
        List<FinishedGoodsInboundDetail> detailList = new ArrayList<>();
        for (InboundDetailCreateVO detailVO : vo.getDetailList()) {
            FinishedGoodsInboundDetail detail = new FinishedGoodsInboundDetail();
            BeanUtils.copyProperties(detailVO, detail);
            detail.setInboundId(inbound.getId());
            detail.setBatchNo(generateBatchNo());
            detail.setCreateTime(new Date());
            detailList.add(detail);
        }
        inboundDetailService.saveBatch(detailList);

        log.info("成品入库单创建成功，入库单号：{}", inbound.getInboundNo());
        return inbound.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void executeInbound(String inboundId) {
        log.info("执行成品入库，入库单ID：{}", inboundId);

        // 1. 获取入库单信息
        FinishedGoodsInbound inbound = this.getById(inboundId);
        if (inbound == null) {
            throw new JeecgBootException("入库单不存在");
        }

        if (inbound.getInboundStatus() == 2) {
            throw new JeecgBootException("入库单已完成，无法重复执行");
        }

        // 2. 获取入库明细
        List<FinishedGoodsInboundDetail> detailList = inboundDetailService.list(
                new LambdaQueryWrapper<FinishedGoodsInboundDetail>()
                        .eq(FinishedGoodsInboundDetail::getInboundId, inboundId)
        );

        // 3. 创建库存记录和日志
        List<FinishedGoodsInventory> inventoryList = new ArrayList<>();
        List<FinishedGoodsInventoryLog> logList = new ArrayList<>();

        for (FinishedGoodsInboundDetail detail : detailList) {
            // 创建库存记录
            FinishedGoodsInventory inventory = new FinishedGoodsInventory();
            inventory.setOrderId(inbound.getOrderId());
            inventory.setOrderNo(inbound.getOrderNo());
            inventory.setOrderDetailId(detail.getOrderDetailId());
            inventory.setWindowSeries(detail.getWindowSeries());
            inventory.setWindowNo(detail.getWindowNo());
            inventory.setWindowColor(detail.getWindowColor());
            inventory.setWarehouseId(detail.getWarehouseId()); // 使用明细级别的仓库ID
            inventory.setLocationId(detail.getLocationId());
            inventory.setBatchNo(detail.getBatchNo());
            inventory.setAvailableQuantity(detail.getActualQuantity());
            inventory.setReservedQuantity(0);
            inventory.setTotalQuantity(detail.getActualQuantity());
            inventory.setStockStatus(1); // 正常
            inventory.setInboundDate(inbound.getInboundDate());
            inventory.setLastUpdateTime(new Date());
            inventory.setCreateTime(new Date());
            inventoryList.add(inventory);

            // 创建库存变动日志
            FinishedGoodsInventoryLog log = new FinishedGoodsInventoryLog();
            log.setInventoryId(inventory.getId());
            log.setOrderNo(inbound.getOrderNo());
            log.setOperationType(1); // 入库
            log.setOperationQuantity(detail.getActualQuantity());
            log.setBeforeQuantity(0);
            log.setAfterQuantity(detail.getActualQuantity());
            log.setOperationReason("成品入库");
            log.setRelatedDocNo(inbound.getInboundNo());
            log.setOperatorName(inbound.getOperatorName());
            log.setCreateTime(new Date());
            logList.add(log);
        }

        // 批量保存库存记录
        inventoryService.saveBatch(inventoryList);

        // 更新库存记录的ID到日志中（因为保存后才有ID）
        for (int i = 0; i < inventoryList.size(); i++) {
            logList.get(i).setInventoryId(inventoryList.get(i).getId());
        }

        // 批量保存库存日志
        inventoryLogService.saveBatch(logList);

        // 4. 更新库位状态
        updateLocationStatus(detailList);

        // 5. 更新入库单状态
        inbound.setInboundStatus(2); // 已完成
        inbound.setUpdateTime(new Date());
        this.updateById(inbound);

        // 5. 更新订单状态为已入库
        updateOrderStatusToInbound(inbound.getOrderId());

        log.info("成品入库执行完成，入库单号：{}", inbound.getInboundNo());
    }

    /**
     * 检查生产计划的包装工种任务是否完成
     */
    private boolean isPackagingTaskCompleted(String planId) {
        try {
            // 查询该计划下的包装工种任务（假设包装工种编码为"PACKAGE"）
            LambdaQueryWrapper<MesProductionPlanTask> taskWrapper = new LambdaQueryWrapper<>();
            taskWrapper.eq(MesProductionPlanTask::getPlanId, planId)
                    .eq(MesProductionPlanTask::getWorkTypeCode, "PACKAGE");

            List<MesProductionPlanTask> packagingTasks = mesProductionPlanTaskService.list(taskWrapper);

            // 检查所有包装任务是否都已完成（状态为3-已完成）
            for (MesProductionPlanTask task : packagingTasks) {
                if (task.getStatus() != 3) { // 未完成
                    return false;
                }
            }

            return !packagingTasks.isEmpty(); // 有包装任务且都已完成
        } catch (Exception e) {
            log.error("检查包装工种完成状态失败，计划ID：{}", planId, e);
            return false;
        }
    }

    @Override
    public boolean checkOrderCanInbound(String orderId) {
        log.info("检查订单是否可以入库，订单ID：{}", orderId);

        try {
            // 1. 检查订单是否存在
            ProductSalesOrder order = productSalesOrderService.getById(orderId);
            if (order == null) {
                log.warn("订单不存在，订单ID：{}", orderId);
                return false;
            }

            // 2. 检查订单状态是否允许入库（状态9-生产完成）
            if (order.getStatus() != 9) {
                log.warn("订单状态不允许入库，当前状态：{}，订单ID：{}", order.getStatus(), orderId);
                return false;
            }

            // 3. 查询该订单的生产计划
            LambdaQueryWrapper<MesProductionPlan> planWrapper = new LambdaQueryWrapper<>();
            planWrapper.eq(MesProductionPlan::getOrderId, orderId);
            List<MesProductionPlan> plans = mesProductionPlanService.list(planWrapper);

            if (plans.isEmpty()) {
                log.warn("订单没有生产计划，订单ID：{}", orderId);
                return false;
            }

            // 4. 检查所有生产计划的包装工种是否完成
            for (MesProductionPlan plan : plans) {
                if (!isPackagingTaskCompleted(plan.getId())) {
                    log.warn("生产计划包装工种未完成，计划ID：{}，订单ID：{}", plan.getId(), orderId);
                    return false;
                }
            }

            log.info("订单可以入库，订单ID：{}", orderId);
            return true;

        } catch (Exception e) {
            log.error("检查订单入库条件失败，订单ID：{}", orderId, e);
            return false;
        }
    }

    @Override
    public IPage<FinishedGoodsInboundVO> queryInboundList(Page<FinishedGoodsInboundVO> page, FinishedGoodsInboundVO query) {
        return finishedGoodsInboundMapper.queryInboundList(page, query);
    }

    @Override
    public FinishedGoodsInboundVO queryInboundDetail(String id) {
        return finishedGoodsInboundMapper.queryInboundDetail(id);
    }

    @Override
    public void updateOrderStatusToInbound(String orderId) {
        log.info("更新订单状态为已入库，订单ID：{}", orderId);

        try {
            // 获取订单信息
            ProductSalesOrder order = productSalesOrderService.getById(orderId);
            if (order == null) {
                log.error("订单不存在，无法更新状态，订单ID：{}", orderId);
                throw new JeecgBootException("订单不存在");
            }

            // 更新订单状态为10（已入库）
            order.setStatus(10);
            order.setUpdateTime(new Date());

            boolean updated = productSalesOrderService.updateById(order);
            if (updated) {
                log.info("订单状态更新成功，订单ID：{}，新状态：10（已入库）", orderId);
            } else {
                log.error("订单状态更新失败，订单ID：{}", orderId);
                throw new JeecgBootException("订单状态更新失败");
            }

        } catch (Exception e) {
            log.error("更新订单状态失败，订单ID：{}", orderId, e);
            throw new JeecgBootException("更新订单状态失败：" + e.getMessage());
        }
    }

    /**
     * 更新库位状态
     */
    private void updateLocationStatus(List<FinishedGoodsInboundDetail> detailList) {
        log.info("更新库位状态，明细数量：{}", detailList.size());

        try {
            for (FinishedGoodsInboundDetail detail : detailList) {
                if (detail.getLocationId() != null) {
                    WmsWarehouseLocation location = warehouseLocationService.getById(detail.getLocationId());
                    if (location != null) {
                        // 更新库位状态为占用（假设1为占用状态）
                        location.setStatus("1");
                        location.setUpdateTime(new Date());
                        warehouseLocationService.updateById(location);
                        log.info("库位状态已更新，库位ID：{}，新状态：占用", detail.getLocationId());
                    }
                }
            }
        } catch (Exception e) {
            log.error("更新库位状态失败", e);
            // 不抛出异常，避免影响主流程
        }
    }

    @Override
    public String generateInboundNo() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dateStr = sdf.format(new Date());

        // 查询当天最大序号
        LambdaQueryWrapper<FinishedGoodsInbound> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(FinishedGoodsInbound::getInboundNo, "RK" + dateStr)
                .orderByDesc(FinishedGoodsInbound::getInboundNo)
                .last("LIMIT 1");

        FinishedGoodsInbound lastInbound = this.getOne(wrapper);

        int nextSeq = 1;
        if (lastInbound != null && lastInbound.getInboundNo() != null) {
            String lastNo = lastInbound.getInboundNo();
            // 提取序号部分（最后3位）
            String seqStr = lastNo.substring(lastNo.length() - 3);
            nextSeq = Integer.parseInt(seqStr) + 1;
        }

        // 生成新的入库单号：RK + 日期 + 3位序号
        return String.format("RK%s%03d", dateStr, nextSeq);
    }

    @Override
    public String generateBatchNo() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timestamp = sdf.format(new Date());

        // 生成批次号：PC + 时间戳 + 2位随机数
        int random = (int) (Math.random() * 100);
        return String.format("PC%s%02d", timestamp, random);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createInboundByOrder(String orderNo, String productionPlanId) {
        log.info("根据订单编号创建成品入库单，订单号：{}，生产计划ID：{}", orderNo, productionPlanId);

        try {
            // 1. 根据订单编号查询订单信息
            LambdaQueryWrapper<ProductSalesOrder> orderWrapper = new LambdaQueryWrapper<>();
            orderWrapper.eq(ProductSalesOrder::getOrderNo, orderNo);
            ProductSalesOrder order = productSalesOrderService.getOne(orderWrapper);

            if (order == null) {
                throw new JeecgBootException("订单不存在，订单号：" + orderNo);
            }

            // 3. 创建入库单主表
            FinishedGoodsInbound inbound = new FinishedGoodsInbound();
            inbound.setOrderId(order.getId());
            inbound.setOrderNo(order.getOrderNo());
            inbound.setProductionPlanId(productionPlanId);
            inbound.setInboundNo(generateInboundNo());
            inbound.setInboundStatus(0); // 待入库
            inbound.setInboundDate(new Date());
            inbound.setWarehouseId("DEFAULT_WAREHOUSE"); // 默认仓库，可根据业务需求调整
            inbound.setOperatorName("SYSTEM"); // 系统自动创建
            inbound.setRemark("生产计划下发自动创建");
            inbound.setCreateTime(new Date());

            // 4. 设置总数量（从订单中获取）  总数量 = 订单明细数量总和
            List<ProductSalesOrderDetail> productSalesOrderDetailList = productSalesOrderDetailService.list(new LambdaQueryWrapper<ProductSalesOrderDetail>()
                    .eq(ProductSalesOrderDetail::getOrderId, order.getId()));

            inbound.setTotalQuantity(productSalesOrderDetailList.stream().mapToInt(ProductSalesOrderDetail::getQuantity).sum());

            // 5. 保存入库单
            this.save(inbound);

            //6.根据成品订单产品明细 创建入库明细
            for (ProductSalesOrderDetail orderDetail : productSalesOrderDetailList) {
                FinishedGoodsInboundDetail detail = new FinishedGoodsInboundDetail();
                detail.setInboundId(inbound.getId());
                detail.setOrderDetailId(orderDetail.getId());
                detail.setWindowSeries(orderDetail.getWindowSeries());
                detail.setWindowNo(orderDetail.getWindowNo());
                detail.setWindowColor(orderDetail.getWindowColor());
                detail.setBatchNo(generateBatchNo());
                detail.setPlannedQuantity(orderDetail.getQuantity());
                detail.setCreateTime(new Date());

                inboundDetailService.save(detail);
            }
            return inbound.getId();

        } catch (Exception e) {
            log.error("根据订单编号创建成品入库单失败，订单号：{}，生产计划ID：{}", orderNo, productionPlanId, e);
            throw new JeecgBootException("创建成品入库单失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void executeBatchInbound(BatchInboundExecuteVO vo) {
        log.info("开始执行分批次入库，入库单ID：{}", vo.getInboundId());

        try {
            // 1. 验证入库单状态
            FinishedGoodsInbound inbound = this.getById(vo.getInboundId());
            if (inbound == null) {
                throw new JeecgBootException("入库单不存在");
            }
            if (inbound.getInboundStatus() == 2) {
                throw new JeecgBootException("入库单已完成，不能重复入库");
            }

            // 2. 获取订单信息
            ProductSalesOrder order = productSalesOrderService.getById(inbound.getOrderId());
            if (order == null) {
                throw new JeecgBootException("关联订单不存在");
            }

            // 3. 处理每个入库明细
            for (BatchInboundExecuteVO.BatchInboundDetailVO detailVO : vo.getDetails()) {
                processInboundDetail(detailVO, order.getOrderNo(),inbound.getInboundNo());
            }

            // 4. 更新入库明细的实际数量
            updateInboundDetailActualQuantity(vo);

            // 5. 检查并更新入库单状态
            updateInboundStatus(vo.getInboundId());

            // 6. 检查并更新订单状态
            updateOrderStatusIfCompleted(inbound.getOrderId());

            log.info("分批次入库执行完成，入库单ID：{}", vo.getInboundId());

        } catch (Exception e) {
            log.error("分批次入库执行失败，入库单ID：{}", vo.getInboundId(), e);
            throw new JeecgBootException("分批次入库执行失败：" + e.getMessage());
        }
    }

    /**
     * 处理单个入库明细
     */
    private void processInboundDetail(BatchInboundExecuteVO.BatchInboundDetailVO detailVO, String orderNo,String inboundNo) {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        // 1. 创建或更新库存记录
        createOrUpdateInventory(detailVO, orderNo,loginUser,inboundNo);
        // 3. 更新库位状态
        updateLocationStatus(detailVO, orderNo,loginUser);
    }

    @Autowired
    private IWmsWarehouseService warehouseService;

    /**
     * 创建或更新库存记录
     */
    private void createOrUpdateInventory(BatchInboundExecuteVO.BatchInboundDetailVO detailVO,
                                         String orderNo,
                                         LoginUser loginUser,
                                         String inboundNo) {

        // 查询是否已存在库存记录
        LambdaQueryWrapper<FinishedGoodsInventory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FinishedGoodsInventory::getOrderNo, orderNo)
                .eq(FinishedGoodsInventory::getOrderDetailId, detailVO.getDetailId())
                .eq(FinishedGoodsInventory::getLocationId, detailVO.getLocationId());

        FinishedGoodsInventory existingInventory = inventoryService.getOne(queryWrapper);

        //判断该订单下该库位是否已存在库存信息  若已存在则判断是否存在当前的明细，若存在则更新明细的库存信息，否则新增库存信息
        if (existingInventory != null) {
            FinishedGoodsInventoryLog log = new FinishedGoodsInventoryLog();
            log.setOrderNo(orderNo);
            log.setOperationType(1);
            log.setOperationQuantity(detailVO.getQuantity());

            log.setBeforeQuantity(existingInventory.getTotalQuantity());
            log.setAfterQuantity(existingInventory.getTotalQuantity() + detailVO.getQuantity());
            log.setCreateTime(new Date());
            log.setInventoryId(existingInventory.getId());
            log.setOperatorId(loginUser.getId());
            log.setOperatorName(loginUser.getRealname());
            log.setOperationReason("生产入库");
            log.setRelatedDocNo(inboundNo);
            inventoryLogService.save(log);
            // 更新现有库存
            existingInventory.setAvailableQuantity(existingInventory.getAvailableQuantity() + detailVO.getQuantity());
            existingInventory.setReservedQuantity(0);
            existingInventory.setTotalQuantity(existingInventory.getTotalQuantity() + detailVO.getQuantity());
            existingInventory.setUpdateTime(new Date());
            inventoryService.updateById(existingInventory);
        } else {
            FinishedGoodsInventoryLog log = new FinishedGoodsInventoryLog();
            log.setOrderNo(orderNo);
            log.setOperationType(1);
            log.setOperationQuantity(detailVO.getQuantity());
            log.setBeforeQuantity(0);
            log.setAfterQuantity(detailVO.getQuantity());
            log.setCreateTime(new Date());
            log.setRelatedDocNo(inboundNo);
            // 创建新库存记录
            FinishedGoodsInventory inventory = new FinishedGoodsInventory();
            inventory.setOrderNo(orderNo);
            ProductSalesOrder order = productSalesOrderService.getProductSalesOrderByOrderNo(orderNo);
            inventory.setOrderId(order.getId());
            inventory.setOrderDetailId(detailVO.getDetailId());
            inventory.setWindowSeries(detailVO.getWindowSeries());
            inventory.setWindowNo(detailVO.getWindowNo());
            inventory.setWindowColor(detailVO.getWindowColor());
            inventory.setWarehouseId(detailVO.getWarehouseId());
            WmsWarehouse warehouse = warehouseService.getById(detailVO.getWarehouseId());
            inventory.setWarehouseName(warehouse.getWarehouseName());
            WmsWarehouseLocation location = warehouseLocationService.getById(detailVO.getLocationId());
            inventory.setLocationId(detailVO.getLocationId());
            inventory.setLocationName(location.getLocationName());
            inventory.setAvailableQuantity(detailVO.getQuantity());
            inventory.setReservedQuantity(0);
            inventory.setTotalQuantity(detailVO.getQuantity());
            inventory.setStockStatus(1);
            inventory.setDelFlag(0);
            inventory.setCreateTime(new Date());
            inventoryService.save(inventory);
            log.setInventoryId(inventory.getId());
            log.setOperatorId(loginUser.getId());
            log.setOperatorName(loginUser.getRealname());
            log.setOperationReason("生产入库");
            inventoryLogService.save(log);
        }
    }


    /**
     * 更新库位状态
     */
    private void updateLocationStatus(BatchInboundExecuteVO.BatchInboundDetailVO detailVO, String orderNo,LoginUser loginUser) {
        // 检查该订单在其他库位是否有库存
        LambdaQueryWrapper<FinishedGoodsInventory> queryWrapper = new LambdaQueryWrapper<>();
        ;
        //获取库位ID并去重
        List<Object> otherInventories = inventoryService.listObjs(queryWrapper
                .eq(FinishedGoodsInventory::getOrderNo, orderNo)
                .ne(FinishedGoodsInventory::getLocationId, detailVO.getLocationId())
                .select(FinishedGoodsInventory::getLocationId)).stream().distinct().collect(Collectors.toList());


        if (!otherInventories.isEmpty()) {
            warehouseLocationService.update(new LambdaUpdateWrapper<WmsWarehouseLocation>()
                    .in(WmsWarehouseLocation::getId, otherInventories)
                    .set(WmsWarehouseLocation::getStatus, "5"));
        }

        // 更新当前库位状态为占用
        WmsWarehouseLocation currentLocation = warehouseLocationService.getById(detailVO.getLocationId());
        if (currentLocation != null && !currentLocation.getStatus().equals("2")) { // 1=占用
            currentLocation.setStatus("2"); // 设置为占用
            currentLocation.setUpdateTime(new Date());
            warehouseLocationService.updateById(currentLocation);
        }
    }

    /**
     * 更新入库明细的实际数量
     */
    private void updateInboundDetailActualQuantity(BatchInboundExecuteVO vo) {
        // 按明细ID分组统计数量
        vo.getDetails().stream()
                .collect(java.util.stream.Collectors.groupingBy(
                        BatchInboundExecuteVO.BatchInboundDetailVO::getDetailId,
                        java.util.stream.Collectors.summingInt(BatchInboundExecuteVO.BatchInboundDetailVO::getQuantity)
                ))
                .forEach((detailId, totalQuantity) -> {
                    FinishedGoodsInboundDetail detail = inboundDetailService.getById(detailId);
                    if (detail != null) {
                        detail.setActualQuantity((detail.getActualQuantity() == null ? 0 : detail.getActualQuantity()) + totalQuantity);
                        inboundDetailService.updateById(detail);
                    }
                });
    }

    /**
     * 检查并更新入库单状态
     */
    private void updateInboundStatus(String inboundId) {
        // 获取入库单所有明细
        List<FinishedGoodsInboundDetail> details = inboundDetailService.list(
                new LambdaQueryWrapper<FinishedGoodsInboundDetail>()
                        .eq(FinishedGoodsInboundDetail::getInboundId, inboundId)
        );

        boolean allCompleted = true;
        boolean hasPartial = false;

        for (FinishedGoodsInboundDetail detail : details) {
            int planned = detail.getPlannedQuantity() == null ? 0 : detail.getPlannedQuantity();
            int actual = detail.getActualQuantity() == null ? 0 : detail.getActualQuantity();

            if (actual < planned) {
                allCompleted = false;
                if (actual > 0) {
                    hasPartial = true;
                }
            }
        }

        FinishedGoodsInbound inbound = this.getById(inboundId);
        if (allCompleted) {
            // 全部完成
            inbound.setInboundStatus(2);
        } else if (hasPartial) {
            // 部分入库
            inbound.setInboundStatus(1);
        }
        inbound.setUpdateTime(new Date());
        this.updateById(inbound);
    }

    /**
     * 检查并更新订单状态
     */
    private void updateOrderStatusIfCompleted(String orderId) {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        // 检查该订单下所有入库单是否都已完成
        List<FinishedGoodsInbound> inbounds = this.list(
                new LambdaQueryWrapper<FinishedGoodsInbound>()
                        .eq(FinishedGoodsInbound::getOrderId, orderId)
        );

        boolean allInboundsCompleted = inbounds.stream()
                .allMatch(inbound -> inbound.getInboundStatus() == 2);

        if (allInboundsCompleted) {
            // 更新订单状态为已入库
            ProductSalesOrder order = productSalesOrderService.getById(orderId);
            Integer oldOrderStatus = order.getStatus();
            if (order != null && oldOrderStatus != 10) {
                order.setStatus(10); // 10=已入库
                order.setUpdateTime(new Date());

                // 添加订单进度表信息
                productSalesOrderService.updateOrderStatus(
                        order.getId(),
                        oldOrderStatus,
                        10,
                        loginUser.getId(),
                        "生产成品入库"
                );
                productSalesOrderService.updateById(order);
            }
        }
    }
}
